package httpclient

import (
	"bytes"
	"encoding/json"
	"encoding/xml"
	"fmt"
	"io"
	"mime/multipart"
	"net/http"
	"net/url"
	"strings"
)

// Request 表示 HTTP 请求
type Request struct {
	Method  string
	URL     string
	Headers map[string]string
	Query   url.Values
	Body    io.Reader
	Form    url.Values
	Files   map[string]string // 文件名 -> 文件路径
}

// NewRequest 创建新的请求
func NewRequest(method, urlStr string) *Request {
	return &Request{
		Method:  method,
		URL:     urlStr,
		Headers: make(map[string]string),
		Query:   url.Values{},
		Form:    url.Values{},
		Files:   make(map[string]string),
	}
}

// WithHeader 设置请求头
func (r *Request) WithHeader(key, value string) *Request {
	r.Headers[key] = value
	return r
}

// WithHeaders 批量设置请求头
func (r *Request) WithHeaders(headers map[string]string) *Request {
	for k, v := range headers {
		r.Headers[k] = v
	}
	return r
}

// WithQuery 设置查询参数
func (r *Request) WithQuery(key, value string) *Request {
	r.Query.Set(key, value)
	return r
}

// WithQueries 批量设置查询参数
func (r *Request) WithQueries(queries map[string]string) *Request {
	for k, v := range queries {
		r.Query.Set(k, v)
	}
	return r
}

// WithJSON 设置 JSON 请求体
func (r *Request) WithJSON(data interface{}) *Request {
	jsonData, err := json.Marshal(data)
	if err != nil {
		return r
	}
	r.Headers["Content-Type"] = "application/json"
	r.Body = bytes.NewReader(jsonData)
	return r
}

// WithXML 设置 XML 请求体
func (r *Request) WithXML(data interface{}) *Request {
	xmlData, err := xml.Marshal(data)
	if err != nil {
		return r
	}
	r.Headers["Content-Type"] = "application/xml"
	r.Body = bytes.NewReader(xmlData)
	return r
}

// WithForm 设置表单数据
func (r *Request) WithForm(key, value string) *Request {
	r.Form.Set(key, value)
	return r
}

// WithForms 批量设置表单数据
func (r *Request) WithForms(forms map[string]string) *Request {
	for k, v := range forms {
		r.Form.Set(k, v)
	}
	return r
}

// WithFile 添加文件
func (r *Request) WithFile(fieldName, filePath string) *Request {
	r.Files[fieldName] = filePath
	return r
}

// Build 构建 HTTP 请求
func (r *Request) Build() (*http.Request, error) {
	// 处理 URL
	reqURL := r.URL
	if len(r.Query) > 0 {
		if strings.Contains(reqURL, "?") {
			reqURL += "&" + r.Query.Encode()
		} else {
			reqURL += "?" + r.Query.Encode()
		}
	}

	// 处理请求体
	var body io.Reader
	if len(r.Files) > 0 {
		// 处理文件上传
		bodyBuf := &bytes.Buffer{}
		writer := multipart.NewWriter(bodyBuf)

		// 添加文件
		for fieldName, filePath := range r.Files {
			file, err := writer.CreateFormFile(fieldName, filePath)
			if err != nil {
				return nil, err
			}
			// TODO: 读取并写入文件内容
			fmt.Println(file)
		}

		// 添加表单数据
		for key, values := range r.Form {
			for _, value := range values {
				if err := writer.WriteField(key, value); err != nil {
					return nil, err
				}
			}
		}

		writer.Close()
		r.Headers["Content-Type"] = writer.FormDataContentType()
		body = bodyBuf
	} else if len(r.Form) > 0 {
		// 处理普通表单
		formData := r.Form.Encode()
		r.Headers["Content-Type"] = "application/x-www-form-urlencoded"
		body = strings.NewReader(formData)
	} else if r.Body != nil {
		// 使用自定义请求体
		body = r.Body
	}

	// 创建请求
	req, err := http.NewRequest(r.Method, reqURL, body)
	if err != nil {
		return nil, err
	}

	// 设置请求头
	for key, value := range r.Headers {
		req.Header.Set(key, value)
	}

	return req, nil
}
